package com.example.api.mall.logic.impl;

import com.example.entity.domain.member.Member;
import com.example.entity.domain.user.User;
import com.example.entity.api.mall.test.UserVo;
import com.example.api.mall.logic.ITestLogic;
import com.example.service.member.service.IMemberService;
import com.example.service.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Transactional(propagation = Propagation.REQUIRED)//默认，如果当前存在事务则加入，如果不存在则创建一个新事务
 * @Transactional(propagation = Propagation.SUPPORTS)//如果当前存在事务则加入，如果不存在则以非事务形式运行
 * @Transactional(propagation = Propagation.MANDATORY)//如果当前存在事务则加入，如果不存在则抛出异常
 * @Transactional(propagation = Propagation.REQUIRES_NEW)//创建新事务，如果当前存在事务则暂停当前事务
 * @Transactional(propagation = Propagation.NOT_SUPPORTED)//非事务方式运行，如果当前存在事务则暂停当前事务
 * @Transactional(propagation = Propagation.NEVER)//非事务方式运行，如果当前存在事务则抛出异常
 * @Transactional(propagation = Propagation.NESTED)//效果和Propagation.REQUIRED一样
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)//使用数据库默认隔离级别
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED)//
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED)//
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)//
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)//
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = -1)//规定时间内没有完成则自动回滚，默认-1没有时间限制，不知道数据库默认的失效时间会不会起作用
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = -1, readOnly = false)//默认false，是否只允许执行只读sql，否则抛出异常
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = -1, readOnly = false, rollbackFor = RuntimeException.class)//默认RuntimeException.class才会抛出异常，可指定多个，例如可以扩展到Exception所有异常
 * @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = -1, readOnly = false, rollbackFor = RuntimeException.class, noRollbackFor = Exception.class)//哪些异常不会回滚事务，可指定多个
 * 注意，事务会因为一些原因失效：
 * @Transactional所在的类必须有Spring来管理
 * 放在执行方法上，方法必须是public
 * 嵌套的事务必须由外部调用
 * TODO 必须配置事务管理器
 * 捕获的异常必须抛出
 */
@Service
@Slf4j
@Transactional(propagation = Propagation.REQUIRED)//默认，如果当前存在事务则加入，如果不存在则创建一个新事务
public class TestLogicImpl implements ITestLogic {

    @Autowired
    private IUserService userService;

    @Autowired
    private IMemberService memberService;

    @Override
    public UserVo test() {
        User user = userService.getById(1);
        Member member = memberService.getById(1);
        return UserVo.builder().user(user).member(member).build();
    }

    @Override
    public UserVo getUser(Long userId) {
        User user = userService.getById(userId);
        return UserVo.builder().user(user).build();
    }
}
